const { Board } = require('board-game');
const extend = require('extend');

const common = require('./common');
const { game: gameConfig } = require('./config');

const getFs = (fs, isFirst) => isFirst ? fs * common.firstPlay : fs;

const numbers = [3, 4, 6, 7, 8, 9];

class CountingBoard extends Board {
    constructor(game) {
        super(game);
        this.count = 1;
        this.round = 1;
        this.number = this.game.groups.length === 6 ? 7 : Math.min(this.game.groups.length - 1, 9);

        this.prev = false;
        this.current = false;
        this.next = false;

        this.tick = 0;
        this.stage = common.stages.index;
        this.interval = setInterval(() => this.step(), 1000);

        this.systemRoleIndex = -15;
    }
    step() {
        this.tick++;
        switch(this.stage) {
            case common.stages.index:
                if (this.tick >= getFs(common.fs.index, this.isFirst)) {
                    this.tick = 0;
                    this.stage = common.stages.starting;
                }
                break;
            case common.stages.starting:
                if (this.tick >= getFs(common.fs.starting, this.isFirst)) {
                    this.tick = 0;
                    this.stage = common.stages.number;
                }
                break;
            case common.stages.number:
                if (this.tick >= getFs(common.fs.number, this.isFirst)) {
                    this.tick = 0;
                    this.stage = common.stages.counting;
                    this.current = this.systemRole;
                    if (!this.next) this.next = this.groups[0].roles[0];
                }
                break;
            case common.stages.counting:
                if (this.current.type === common.role.system) {
                    if (this.tick >= common.fs.system) {
                        this.nextCount();
                        this.tick = 0;
                    }
                } else {
                    if (this.tick >= getFs(common.fs.counting, this.isFirst)) {
                        this.wrong(this.current, common.wrong.timeout);
                        this.tick = 0;
                    }
                }
                break;
            case common.stages.wrong:
                if (!this.settings.wrongConfirm) {
                    if (this.tick >= getFs(common.fs.wrong, this.isFirst)) {
                        this.stage = common.stages.counting;
                        this.tick = 0;
                    }
                }
                break;
        }
    }
    get isFirst() {
        return this.settings.firstPlay && this.round === 1 && this.number <= this.groups.length;
    }
    nextCount() {
        this.count++;
        if (this.count > this.number * 10) {
            this.nextRound();
        } else {
            this.prev && this.prev.clearStatus();
            this.prev = this.current;
            this.current = this.next;
            this.next = this.groups[(this.current.group + 1) % this.groups.length].roles[0];
        }
    }
    nextRound() {
        this.round++;
        if (this.round > gameConfig.minRound) {
            // let winGroup = this.checkWin();
            // if (winGroup) {
            //     //todo: 游戏结束
            //     return;
            // }
            this.game.over();
            clearInterval(this.interval);
            return;
        }
        this.count = 1;
        this.tick = 0;
        this.number = numbers[Math.floor(numbers.length * Math.random())];
        this.stage = common.stages.number;
        this.prev && this.prev.clearStatus();
        this.prev = this.current;
        this.current = this.systemRole;
        this.next = this.groups[(this.prev.group + 1) % this.groups.length].roles[0];
    }
    get systemRole() {
        let data = {
            type: common.role.system,
            count: this.count,
            right: true,
            group: -1,
            player: {
                id: this.systemRoleIndex--,
                name: '系统'
            },
        };
        return extend(true, { }, data, {
            clearStatus() { },
            data,
        });
    }
    wrong(role, type) {
        role.doWrong(type, this.count);
        this.stage = common.stages.wrong;
    }
    confirmWrong() {
        this.prev && this.prev.clearStatus();
        this.prev = this.current;
        this.count--;
        this.current = this.systemRole;
        this.current.count = this.count;
        this.tick = 0;
        this.stage = common.stages.counting;
    }
    right(role) {
        role.doRight(this.count);
        this.nextCount();
        this.tick = 0;
        this.stage = common.stages.counting;
    }
    doCount(role) {
        if (this.current !== role) return;
        if (this.count % this.number === 0) {
            this.wrong(role, common.wrong.divisible);
        } else if (this.count % 10 === this.number) {
            this.wrong(role, common.wrong.single);
        } else if (Math.floor(this.count / 10) === this.number) {
            this.wrong(role, common.wrong.ten);
        } else {
            this.right(role);
        }
    }
    doPass(role) {
        if (this.current !== role) return;
        if (this.count % this.number === 0) {
            this.right(role);
        } else if (this.count % 10 === this.number) {
            this.right(role);
        } else if (Math.floor(this.count / 10) === this.number) {
            this.right(role);
        } else {
            this.wrong(role, common.wrong.pass);
        }
    }
    get prevInfo() {
        return this.prev ? this.prev.data : false;
    }
    get currentInfo() {
        return this.current ? this.current.data : false;
    }
    get nextInfo() {
        return this.next ? this.next.data : false;
    }
    get roleInfos() {
        return [
            this.prevInfo,
            this.currentInfo,
            this.nextInfo
        ]
    }
    get countdown() {
        if (this.stage === common.stages.counting && this.current.type === common.role.system) {
            return common.fs.system - this.tick;
        } else if(this.stage === common.stages.wrong && this.settings.wrongConfirm) {
            return 0;
        } else {
            return getFs(common.fs[this.stage], this.isFirst) - this.tick;
        }
    }
    get data() {
        return {
            number: this.number,
            count: this.count,
            round: this.round,
            tick: this.tick,
            stage: this.stage,
            countdown: this.countdown,
            prev: this.prevInfo,
            current: this.currentInfo,
            next: this.nextInfo,
            roles: this.roleInfos,
        };
    }
    get checkWin() {

    }
}

module.exports = CountingBoard;